
$identify("org/mathdox/formulaeditor/modules/logic1/equivalent.js");

$require("org/mathdox/parsing/ParserGenerator.js");
$require("org/mathdox/formulaeditor/parsing/openmath/OpenMathParser.js");
$require("org/mathdox/formulaeditor/parsing/expression/ExpressionParser.js");
$require("org/mathdox/formulaeditor/semantics/MultaryOperation.js");
$require("org/mathdox/formulaeditor/semantics/Keyword.js");

$main(function(){

  var symbol = {
    onscreen : "⇔",
    openmath : null, // use default with model:cd and model:name
    mathml   : "<mo>⇔</mo>"
  };

  /**
   * Define a semantic tree node that represents logic1.equivalent.
   */
  org.mathdox.formulaeditor.semantics.Logic1Equivalent =
    $extend(org.mathdox.formulaeditor.semantics.MultaryOperation, {

      symbol : {

        onscreen : symbol.onscreen,
        openmath : "<OMS cd='logic1' name='equivalent'/>",
        mathml   : symbol.mathml

      },

      precedence : 70

    });
  
  /**
   * Extend the OpenMathParser object with parsing code for logic1.equivalent.
   */
  org.mathdox.formulaeditor.parsing.openmath.OpenMathParser =
    $extend(org.mathdox.formulaeditor.parsing.openmath.OpenMathParser, {

    /**
     * Returns an equality object based on the OpenMath node.
     */
    handleLogic1Equivalent : function(node) {

      // parse the children of the OMA
      var children = node.getChildNodes();
      var operands = [];
      for (var i=1; i<children.length; i++) {
        operands.push(this.handle(children.item(i)));
      }

      // construct the corresponding object
      var result = new org.mathdox.formulaeditor.semantics.Logic1Equivalent();
      result.initialize.apply(result, operands);
      return result;

    }

  });

  org.mathdox.formulaeditor.parsing.openmath.KeywordList["logic1__equivalent"] = new org.mathdox.formulaeditor.semantics.Keyword("logic1", "equivalent", symbol, "infix");

  /**
   * Extend the ExpressionParser object with parsing code for the equality sign.
   */
  var semantics = org.mathdox.formulaeditor.semantics;
  var pG = new org.mathdox.parsing.ParserGenerator();

  if ( "<=>" == "⇔" ) {
    // only one expression, same on screen
    org.mathdox.formulaeditor.parsing.expression.ExpressionParser =
      $extend(org.mathdox.formulaeditor.parsing.expression.ExpressionParser, {

      // expression70 = equivalent | super.expression70
      expression70 : function() {
        var parent = arguments.callee.parent;
        pG.alternation(
          pG.rule("logic1equivalent"),
          parent.expression70).apply(this, arguments);
      },

      // logic1equivalent = 
      //    expression70 "<=>" expression80
      logic1equivalent :
        pG.transform(
          pG.concatenation(
            pG.rule("expression70"),
            pG.literal("<=>"),
            pG.rule("expression80")
          ),
          function(result) {
            return new semantics.Logic1Equivalent(result[0], result[2]);
          }
        )

      });
    } else { // allow alternative as displayed on the screen
      org.mathdox.formulaeditor.parsing.expression.ExpressionParser =
        $extend(org.mathdox.formulaeditor.parsing.expression.ExpressionParser, {

        // expression70 = logic1equivalent | 
        //   logic1equivalentalt | super.expression70
        expression70 : function() {
          var parent = arguments.callee.parent;
          pG.alternation(
            pG.rule("logic1equivalent"),
            pG.rule("logic1equivalentalt"),
            parent.expression70).apply(this, arguments);
        },

        // logic1equivalent = 
        //    expression70 "<=>" expression80
        logic1equivalent :
          pG.transform(
            pG.concatenation(
              pG.rule("expression70"),
              pG.literal("<=>"),
              pG.rule("expression80")
            ),
            function(result) {
              return new semantics.Logic1Equivalent(result[0], result[2]);
            }
          ),

        // logic1equivalentalt = 
        //    expression70 "⇔" expression80
        logic1equivalentalt :
          pG.transform(
            pG.concatenation(
              pG.rule("expression70"),
              pG.literal("⇔"),
              pG.rule("expression80")
            ),
            function(result) {
              return new semantics.Logic1Equivalent(result[0], result[2]);
            }
          )

      });
    }

});
